package com.kc.business.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.kc.business.domain.BizScenic;
import com.kc.business.domain.order.dto.BizOrderStatisticsByAgeSectionDTO;
import com.kc.business.domain.order.dto.BizOrderStatisticsIncomeDetailsDTO;
import com.kc.business.domain.order.dto.BizSaleRankingDTO;
import com.kc.business.domain.order.entity.BizCancelOrderStatistics;
import com.kc.business.domain.order.entity.BizOrderStatistics;
import com.kc.business.domain.query.BizOrderStatisticsQuery;
import com.kc.business.domain.vo.BizOrderMoneyDTO;
import com.kc.business.domain.vo.KcUserStatisticsVO;
import com.kc.business.mapper.BizCelebrityMapper;
import com.kc.business.mapper.BizOrderStatisticsMapper;
import com.kc.business.mapper.BizScenicBusinessMapper;
import com.kc.business.mapper.BizScenicMapper;
import com.kc.business.service.BizCancelOrderStatisticsService;
import com.kc.business.service.BizOrderStatisticsDataService;
import com.kc.business.service.BizOrderStatisticsService;
import com.kc.common.utils.StringUtils;
import com.kc.common.utils.base.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName BizOrderStatisticsDataImpl
 * @Description TODO
 * @Author wangdongliang
 * @Date 2021/5/28 15:36
 */
@Service
@Slf4j
public class BizOrderStatisticsDataServiceImpl implements BizOrderStatisticsDataService {
    @Resource
    private BizScenicMapper bizScenicMapper;
    @Resource
    private BizScenicBusinessMapper bizScenicBusinessMapper;
    @Resource
    private BizCelebrityMapper bizCelebrityMapper;
    @Resource
    private RedisTemplate redisTemplate;


    @Resource
    private BizOrderStatisticsMapper bizOrderStatisticsMapper;
    @Resource
    private BizOrderStatisticsService orderStatisticsService;
    @Resource
    private BizCancelOrderStatisticsService bizCancelOrderStatisticsService;
    @Override
    public List<BizOrderStatistics> getSaleData(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        String tablename = "kc_order_statistics";
        bizOrderStatisticsQuery.setTablename(tablename);
        List<BizOrderStatistics> bizOrderStatisticsList = new ArrayList<>();
        if(StringUtils.isNotEmpty(bizOrderStatisticsQuery.getBeginDate())) {
            bizOrderStatisticsList = orderStatisticsService.getList(bizOrderStatisticsQuery);
        }else if(StringUtils.isNotEmpty(bizOrderStatisticsQuery.getMonth())){
            bizOrderStatisticsQuery.setBeginDate(bizOrderStatisticsQuery.getMonth()+"-01");
            bizOrderStatisticsQuery.setEndDate(DateUtil.endOfMonth(DateUtil.parse(bizOrderStatisticsQuery.getMonth()+"-01")).toString().substring(0,10));
            bizOrderStatisticsList = orderStatisticsService.getList(bizOrderStatisticsQuery);
        }else{
            if(bizOrderStatisticsQuery.getIsQuarter() == 1){
                //季度
                bizOrderStatisticsList = orderStatisticsService.getListByQuarter(bizOrderStatisticsQuery);
            }else {
                bizOrderStatisticsQuery.setBeginMonth(bizOrderStatisticsQuery.getYear() + "-01");
                bizOrderStatisticsQuery.setEndMonth(bizOrderStatisticsQuery.getYear() + "-12");
                bizOrderStatisticsList = orderStatisticsService.getListByMonth(bizOrderStatisticsQuery);
            }
        }
        return bizOrderStatisticsList;
    }

    @Override
    public List<BizCancelOrderStatistics> getCancelData(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        String tablename = "kc_cancel_order_statistics";
        bizOrderStatisticsQuery.setTablename(tablename);
        List<BizCancelOrderStatistics> bizOrderStatisticsList = new ArrayList<>();
        if(StringUtils.isNotEmpty(bizOrderStatisticsQuery.getBeginDate())) {
            bizOrderStatisticsList = bizCancelOrderStatisticsService.getList(bizOrderStatisticsQuery);
        }else if(StringUtils.isNotEmpty(bizOrderStatisticsQuery.getMonth())){
            bizOrderStatisticsQuery.setBeginDate(bizOrderStatisticsQuery.getMonth()+"-01");
            bizOrderStatisticsQuery.setEndDate(DateUtil.endOfMonth(DateUtil.parse(bizOrderStatisticsQuery.getMonth()+"-01")).toString().substring(0,10));
            bizOrderStatisticsList = bizCancelOrderStatisticsService.getList(bizOrderStatisticsQuery);
        }else{
            if(bizOrderStatisticsQuery.getIsQuarter() == 1){
                //季度
                List<BizOrderStatistics> orderStatisticsList = orderStatisticsService.getListByQuarter(bizOrderStatisticsQuery);
                for(BizOrderStatistics bizOrderStatistics : orderStatisticsList){
                    BizCancelOrderStatistics bizCancelOrderStatistics = new BizCancelOrderStatistics();
                    BeanUtils.copyProperties(bizOrderStatistics,bizCancelOrderStatistics);
                    bizOrderStatisticsList.add(bizCancelOrderStatistics);
                }
            }else {
                bizOrderStatisticsQuery.setBeginMonth(bizOrderStatisticsQuery.getYear() + "-01");
                bizOrderStatisticsQuery.setEndMonth(bizOrderStatisticsQuery.getYear() + "-12");
                bizOrderStatisticsList = bizCancelOrderStatisticsService.getListByMonth(bizOrderStatisticsQuery);
            }
        }
        return bizOrderStatisticsList;
    }

    @Override
    public List<BizCancelOrderStatistics> getRefundData(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        return null;
    }

    @Override
    public int getSaleDateByWeek(String attributeName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        BizOrderStatisticsQuery bizOrderStatisticsQuery = new BizOrderStatisticsQuery();
        bizOrderStatisticsQuery.setTablename("kc_order_statistics");
        String currDate = DateUtil.now().substring(0,10);
        String beginDate = DateUtil.offset(DateUtil.parse(currDate), DateField.DAY_OF_MONTH,-7).toString().substring(0,10);
        bizOrderStatisticsQuery.setBeginDate(beginDate);
        bizOrderStatisticsQuery.setEndDate(currDate);
        List<BizOrderStatistics> bizOrderStatisticsList = orderStatisticsService.getList(bizOrderStatisticsQuery);
        int sum = 0;
        for (BizOrderStatistics bizOrderStatistics : bizOrderStatisticsList){
           Method m = bizOrderStatistics.getClass().getMethod("get" + attributeName);
           Object value = m.invoke(bizOrderStatistics);
           //sum += Integer.parseInt(value.toString();
            //Integer aa = Integer.parseInt(value.toString());
           sum += new BigDecimal(value.toString()).intValue();

        }
        return sum;
    }

    @Override
    public int getSaleDateByMonth(String attributeName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        BizOrderStatisticsQuery bizOrderStatisticsQuery = new BizOrderStatisticsQuery();
        bizOrderStatisticsQuery.setTablename("kc_order_statistics");
        String currDate = DateUtil.now().substring(0,10);
        String beginDate = DateUtil.offset(DateUtil.parse(currDate), DateField.DAY_OF_MONTH,-30).toString().substring(0,10);
        bizOrderStatisticsQuery.setBeginDate(beginDate);
        bizOrderStatisticsQuery.setEndDate(currDate);
        List<BizOrderStatistics> bizOrderStatisticsList = orderStatisticsService.getList(bizOrderStatisticsQuery);
        int sum = 0;
        for (BizOrderStatistics bizOrderStatistics : bizOrderStatisticsList){
            Method m = bizOrderStatistics.getClass().getMethod("get" + attributeName);
            Object value = m.invoke(bizOrderStatistics);
            //sum += Integer.parseInt(value.toString());
            sum += new BigDecimal(value.toString()).intValue();
        }
        return sum;
    }

    @Override
    public int getCancelOrderDateByWeek(String attributeName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        BizOrderStatisticsQuery bizOrderStatisticsQuery = new BizOrderStatisticsQuery();
        bizOrderStatisticsQuery.setTablename("kc_cancel_order_statistics");
        String currDate = DateUtil.now().substring(0,10);
        String beginDate = DateUtil.offset(DateUtil.parse(currDate), DateField.DAY_OF_MONTH,-7).toString().substring(0,10);
        bizOrderStatisticsQuery.setBeginDate(beginDate);
        bizOrderStatisticsQuery.setEndDate(currDate);
        List<BizCancelOrderStatistics> bizCancelOrderStatisticsList = bizCancelOrderStatisticsService.getList(bizOrderStatisticsQuery);
        int sum = 0;
        for (BizCancelOrderStatistics bizOrderStatistics : bizCancelOrderStatisticsList){
            Method m = bizOrderStatistics.getClass().getMethod("get" + attributeName);
            Object value = m.invoke(bizOrderStatistics);
            //sum += Integer.parseInt(value.toString());
            sum += new BigDecimal(value.toString()).intValue();
        }
        return sum;
    }

    @Override
    public int getCancelOrderDateByMonth(String attributeName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        BizOrderStatisticsQuery bizOrderStatisticsQuery = new BizOrderStatisticsQuery();
        bizOrderStatisticsQuery.setTablename("kc_cancel_order_statistics");
        String currDate = DateUtil.now().substring(0,10);
        String beginDate = DateUtil.offset(DateUtil.parse(currDate), DateField.DAY_OF_MONTH,-30).toString().substring(0,10);
        bizOrderStatisticsQuery.setBeginDate(beginDate);
        bizOrderStatisticsQuery.setEndDate(currDate);
        List<BizCancelOrderStatistics> bizCancelOrderStatisticsList = bizCancelOrderStatisticsService.getList(bizOrderStatisticsQuery);
        int sum = 0;
        for (BizCancelOrderStatistics bizOrderStatistics : bizCancelOrderStatisticsList){
            Method m = bizOrderStatistics.getClass().getMethod("get" + attributeName);
            Object value = m.invoke(bizOrderStatistics);
            //sum += Integer.parseInt(value.toString());
            sum += new BigDecimal(value.toString()).intValue();
        }
        return sum;
    }

    @Override
    public int getRefundOrderDateByWeek(String attributeName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        BizOrderStatisticsQuery bizOrderStatisticsQuery = new BizOrderStatisticsQuery();
        bizOrderStatisticsQuery.setTablename("kc_cancel_order_statistics");
        String currDate = DateUtil.now().substring(0,10);
        String beginDate = DateUtil.offset(DateUtil.parse(currDate), DateField.DAY_OF_MONTH,-7).toString().substring(0,10);
        bizOrderStatisticsQuery.setBeginDate(beginDate);
        bizOrderStatisticsQuery.setEndDate(currDate);
        List<BizOrderStatistics> bizOrderStatisticsList = orderStatisticsService.getKcRefundStatistics(bizOrderStatisticsQuery);
        int sum = 0;
        for (BizOrderStatistics bizOrderStatistics : bizOrderStatisticsList){
            Method m = bizOrderStatistics.getClass().getMethod("get" + attributeName);
            Object value = m.invoke(bizOrderStatistics);
            //sum += Integer.parseInt(value.toString());
            sum += new BigDecimal(value.toString()).intValue();
        }
        return sum;
    }

    @Override
    public int getRefundOrderDateByMonth(String attributeName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        BizOrderStatisticsQuery bizOrderStatisticsQuery = new BizOrderStatisticsQuery();
        bizOrderStatisticsQuery.setTablename("kc_cancel_order_statistics");
        String currDate = DateUtil.now().substring(0,10);
        String beginDate = DateUtil.offset(DateUtil.parse(currDate), DateField.DAY_OF_MONTH,-30).toString().substring(0,10);
        bizOrderStatisticsQuery.setBeginDate(beginDate);
        bizOrderStatisticsQuery.setEndDate(currDate);
        List<BizOrderStatistics> bizOrderStatisticsList = orderStatisticsService.getKcRefundStatistics(bizOrderStatisticsQuery);
        int sum = 0;
        for (BizOrderStatistics bizOrderStatistics : bizOrderStatisticsList){
            Method m = bizOrderStatistics.getClass().getMethod("get" + attributeName);
            Object value = m.invoke(bizOrderStatistics);
            //sum += Integer.parseInt(value.toString());
            sum += new BigDecimal(value.toString()).intValue();
        }
        return sum;
    }

    @Override
    public int getDays(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        if(bizOrderStatisticsQuery.getYear() != null){
            return 365;
        }else if(StringUtils.isNotEmpty(bizOrderStatisticsQuery.getMonth())){
            bizOrderStatisticsQuery.setBeginDate(bizOrderStatisticsQuery.getMonth()+"-01");
            bizOrderStatisticsQuery.setEndDate(DateUtil.endOfMonth(DateUtil.parse(bizOrderStatisticsQuery.getMonth()+"-01")).toString().substring(0,10));
        }
        int betweenDay = (int) DateUtil.between(DateUtil.parse(bizOrderStatisticsQuery.getBeginDate()), DateUtil.parse(bizOrderStatisticsQuery.getEndDate()), DateUnit.DAY);
        return betweenDay;
    }

    @Override
    public int getSun(List<String> data) {
        int sum = 0;
        for(String s : data){
            int aa = new BigDecimal(s).intValue();
            sum += aa;
        }
        return sum;
    }

    @Override
    public List<KcUserStatisticsVO> getOrderMoney(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        BigDecimal platformMoney = new BigDecimal(0);
        List<BizOrderMoneyDTO> bizOrderMoneyDTOS = bizOrderStatisticsMapper.getOrderMoney(bizOrderStatisticsQuery);
        //log.info("根据条件查到的数据{}",bizOrderMoneyDTOS);
        Map<Integer,Object> map = new HashMap<>();
        if(bizOrderMoneyDTOS != null && bizOrderMoneyDTOS.size() != 0){
            for(BizOrderMoneyDTO bizOrderMoneyDTO : bizOrderMoneyDTOS){
                if(bizOrderMoneyDTO.getGoodsType() >= 0){
                    platformMoney = platformMoney.add(bizOrderMoneyDTO.getOrderMoney());
                }else{
                    map.put(bizOrderMoneyDTO.getGoodsType(),bizOrderMoneyDTO.getOrderMoney());
                }
            }
        }
        map.put(0,platformMoney);
        Map<Integer,String> platformMap = getPlatformList();
        //饼状图数据
        List<KcUserStatisticsVO> kcUserStatisticsVOS = new ArrayList<>();
        for(Map.Entry<Integer,String> entry : platformMap.entrySet()){
            kcUserStatisticsVOS.add(new KcUserStatisticsVO(entry.getValue(),map.get(entry.getKey()) == null ? "0" : map.get(entry.getKey()).toString()));
        }
        return kcUserStatisticsVOS;
    }

    @Override
    public List<KcUserStatisticsVO> getAllPayOrderMoney(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        BigDecimal platformMoney = new BigDecimal("0.0");
        List<BizOrderMoneyDTO> bizOrderMoneyDTOS = bizOrderStatisticsMapper.getPayOrderMoney(bizOrderStatisticsQuery);
        //log.info("根据条件查到的数据{}",bizOrderMoneyDTOS);
        Map<Integer,Object> map = new HashMap<>();
        if(bizOrderMoneyDTOS != null && bizOrderMoneyDTOS.size() != 0){
            for(BizOrderMoneyDTO bizOrderMoneyDTO : bizOrderMoneyDTOS){
                if(bizOrderMoneyDTO.getGoodsType() >= 0){
                    platformMoney= platformMoney.add(bizOrderMoneyDTO.getOrderMoney());
                }else{
                    map.put(bizOrderMoneyDTO.getGoodsType(),bizOrderMoneyDTO.getOrderMoney());
                }
            }
        }
        map.put(0,platformMoney);

        Map<Integer,String> platformMap = getPlatformList();
        //饼状图数据
        List<KcUserStatisticsVO> kcUserStatisticsVOS = new ArrayList<>();
        for(Map.Entry<Integer,String> entry : platformMap.entrySet()){
            kcUserStatisticsVOS.add(new KcUserStatisticsVO(entry.getValue(),map.get(entry.getKey()) == null ? "0" : map.get(entry.getKey()).toString()));
        }
        return kcUserStatisticsVOS;
    }

    @Override
    public List<BizSaleRankingDTO> getSaleRanking(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        //所有订单数据
        List<BizOrderMoneyDTO> allOrderMoney = bizOrderStatisticsMapper.getOrderMoneyByPlatform(bizOrderStatisticsQuery);
        //已支付订单数据
        List<BizOrderMoneyDTO> payOrderMoney = bizOrderStatisticsMapper.getPayOrderMoneyByPlatform(bizOrderStatisticsQuery);
        //将已支付订单数据相关存入map
        Map<String,Object> map = new HashMap<>();
        BigDecimal payOrderTotalMoney = new BigDecimal(0);
        for (BizOrderMoneyDTO bizOrderMoneyDTO : payOrderMoney){
            if(bizOrderMoneyDTO.getGoodsType() >= 0){
                payOrderTotalMoney = payOrderTotalMoney.add(bizOrderMoneyDTO.getOrderMoney());
            }else{
                map.put(bizOrderMoneyDTO.getMerchid()+"-"+ bizOrderMoneyDTO.getGoodsType(),bizOrderMoneyDTO.getOrderMoney());
            }
        }
        map.put("0-0",payOrderTotalMoney);
        //拼装总数据
        List<BizSaleRankingDTO> bizSaleRankingDTOList = new ArrayList<>();
        BigDecimal allOrderTotalMoney = new BigDecimal(0);
        for(BizOrderMoneyDTO bizOrderMoneyDTO : allOrderMoney){
            if(bizOrderMoneyDTO.getGoodsType() >= 0){
                allOrderTotalMoney = allOrderTotalMoney.add(bizOrderMoneyDTO.getOrderMoney());
            }else{
//                map.put(bizOrderMoneyDTO.getMerchid()+"-"+ bizOrderMoneyDTO.getGoodsType(),bizOrderMoneyDTO.getOrderMoney());
                Object obj = map.get(bizOrderMoneyDTO.getMerchid()+"-"+ bizOrderMoneyDTO.getGoodsType());
                BizSaleRankingDTO bizSaleRankingDTO = new BizSaleRankingDTO(getPlatformName(bizOrderMoneyDTO.getGoodsType(),bizOrderMoneyDTO.getMerchid()),bizOrderMoneyDTO.getOrderMoney(),obj == null ? new BigDecimal(0):new BigDecimal(obj.toString()));
                bizSaleRankingDTOList.add(bizSaleRankingDTO);
            }
        }
        BizSaleRankingDTO bizSaleRankingDTO = new BizSaleRankingDTO("平台",allOrderTotalMoney,payOrderTotalMoney);
        bizSaleRankingDTOList.add(bizSaleRankingDTO);
        //排序
        Collections.sort(bizSaleRankingDTOList, new Comparator<BizSaleRankingDTO>() {
            @Override
            public int compare(BizSaleRankingDTO o1, BizSaleRankingDTO o2) {
                //降序
                return o2.getPayMoney().compareTo(o1.getPayMoney());
            }
        });
//        for (BizSaleRankingDTO bizSaleRankingDTO : bizSaleRankingDTOList){
//
//        }
        return bizSaleRankingDTOList;
    }

    @Override
    public List<BizOrderStatisticsIncomeDetailsDTO> getSaleIncomeList(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        List<BizOrderStatistics> orderStatisticsList = getSaleData(bizOrderStatisticsQuery);
        //拼裝銷售收入数据
        List<BizOrderStatisticsIncomeDetailsDTO> statisticsIncomeDetailsDTOS = new ArrayList<>();
        for(BizOrderStatistics bizOrderStatistics : orderStatisticsList){
            BizOrderStatisticsIncomeDetailsDTO bizOrderStatisticsIncomeDetailsDTO = new BizOrderStatisticsIncomeDetailsDTO();
            bizOrderStatisticsIncomeDetailsDTO.setDate(StringUtils.isNotEmpty(bizOrderStatistics.getYearDay())?bizOrderStatistics.getYearDay():bizOrderStatistics.getCurrMonth());
            bizOrderStatisticsIncomeDetailsDTO.setSaleMoney(bizOrderStatistics.getOrderMoney());
            bizOrderStatisticsIncomeDetailsDTO.setSaleCost(bizOrderStatistics.getCostMoney());
            bizOrderStatisticsIncomeDetailsDTO.setSaleProfit(bizOrderStatistics.getOrderMoney().subtract(bizOrderStatistics.getCostMoney()));
            bizOrderStatisticsIncomeDetailsDTO.setIncome(bizOrderStatisticsIncomeDetailsDTO.getSaleCost().add(bizOrderStatisticsIncomeDetailsDTO.getSaleProfit()));
            bizOrderStatisticsIncomeDetailsDTO.setProfitMargin(bizOrderStatisticsIncomeDetailsDTO.getIncome().compareTo(new BigDecimal("0")) == 0 ? "0%" :(bizOrderStatisticsIncomeDetailsDTO.getSaleProfit().divide(bizOrderStatisticsIncomeDetailsDTO.getIncome(),2,BigDecimal.ROUND_HALF_EVEN).multiply(new BigDecimal(100))+"%"));
            statisticsIncomeDetailsDTOS.add(bizOrderStatisticsIncomeDetailsDTO);
        }
        return statisticsIncomeDetailsDTOS;
    }

    @Override
    public List<BizOrderStatisticsByAgeSectionDTO> getSaleStatisticsByAge(BizOrderStatisticsQuery bizOrderStatisticsQuery) {
        List<BizOrderStatisticsByAgeSectionDTO> ageSectionDTOS = bizOrderStatisticsMapper.getSaleStatisticsByAge(bizOrderStatisticsQuery);
        return ageSectionDTOS;
    }

    /**
     * 获取平台名称
     * @param platformType
     * @param platformId
     * @return
     */
    public String getPlatformName(Integer platformType,Integer platformId){
        String platformName = "";
        String key = platformType + ":" + platformId;
        Object obj = redisTemplate.opsForValue().get(key);
        if(obj == null) {
            if (platformType == -1) {
                try {
                    platformName = bizScenicMapper.selectByPrimaryKey(platformId).getScenicName();
                }catch (Exception e){
                    platformName = "";
                }
            } else if (platformType == -2) {
                try {
                    platformName = bizCelebrityMapper.selectByPrimaryKey(platformId).getListName();
                }catch (Exception e){
                    platformName = "";
                }
            } else if (platformType == -4) {
                try {
                    platformName = bizScenicBusinessMapper.selectByPrimaryKey(platformId).getName();
                }catch (Exception e){
                    platformName = "";
                }
            }
            Integer num = RandomUtil.randomInt(3600, 7200);
            redisTemplate.opsForValue().set(key, platformName, num, TimeUnit.SECONDS);
        }else{
            platformName = obj.toString();
        }
        return platformName;
    }

    public Map<Integer,String> getPlatformList(){
        Map<Integer,String> platformMap = new HashMap<>();
        platformMap.put(0,"官方");
        platformMap.put(-1,"景区");
        platformMap.put(-2,"名家");
        platformMap.put(-3,"市场");
        platformMap.put(-4,"商家");
        return platformMap;
    }
}
